ijkplayer编译so库真没那么难

引言

公司现在的电台项目是我第二个接触音频播放项目,Android音视频
播放很多还是使用的MediaPlayer(大中厂除外),但是如果你用过
MediaPlayer的话,很多开发者都会吐槽有多坑,连谷歌官方都推荐
使用ExoPlayer...遇到过最坑的就是播放在线音视频的时候,网络不好
会一直加载,然后点多了还容易ANR...以前就一直想把音频播放这个
换掉,通过自行搜索和问别人,又下面几个方案(小作坊不可能
另外去写个编解码播放库):

  • ExoPlayer:Demo复杂得一匹...而且网上的资料也不是很多,pass;
  • Vitamio:自用免费,商用收费,直接就pass了;
  • 自己编译ffmpeg:一听就很复杂的,同样Pass;
  • ijkplayer:大B站开源的基于FFmpeg的轻量级
    Android/iOS视频播放器,网上资料挺多的,而且官方
    也有维护,虽然还有1600多个issues,和mediaplayer
    差不多的接口,学习成本也不高,可以加进来试试水!

最后就决定使用ijkplayer来替换原先的MediaPlayer了!


1.如何使用ijkplayer

官方https://github.com/Bilibili/ijkplayer

build.gradle添加下述依赖引用即可:

dependencies {
    # 对于大部分的设备来说已经够用了
    compile 'tv.danmaku.ijk.media:ijkplayer-java:0.8.4'
    compile 'tv.danmaku.ijk.media:ijkplayer-armv7a:0.8.4'

    # Other ABIs: 可选
    compile 'tv.danmaku.ijk.media:ijkplayer-armv5:0.8.4'
    compile 'tv.danmaku.ijk.media:ijkplayer-arm64:0.8.4'
    compile 'tv.danmaku.ijk.media:ijkplayer-x86:0.8.4'
    compile 'tv.danmaku.ijk.media:ijkplayer-x86_64:0.8.4'

    # ExoPlayer as IMediaPlayer: optional, experimental
    compile 'tv.danmaku.ijk.media:ijkplayer-exo:0.8.4'
}

这里简单说点东西来解除你可能存在的一些疑惑:

armv7aarmv5arm64x86x86_64 这些是对应的CPU架构,
一般来说准备一个armv7a就基本够了,如果系统找不到CPU架构
对应的so库会去找armeabi,多依赖一些架构只是稍微会快一点,
但是这样也伴随着apk体积的增大,这个需要你自行去权衡!!!
反正笔者就只有一个:armv7a,暂时没发现什么不服!

然后使用方法和MediaPlayer大同小异,这就不另外讲述怎么
使用了,网上一搜也很多。接下来要说下笔者遇到的一个问题:

ijkplayer默认不支持HTTPS

是的,不支持,如果你尝试使用ijkplayer播放Https开头的音频,会报这样的错误:

除了去编译ijkplayer的源码,没有其他选择,编译这玩意可把我
坑惨了,各种不懂,碰壁,不过最后所幸还是捣鼓成功了,顺道
记录下,方便后来者(顺道吐槽下网上各种抄的文章,搜到的基本
都是一样的...)


2.编译支持Https的ijkplayer

不要问我Windows上怎么编译,反正我只会Ubuntu和MAC上编译!
笔者在Ubuntu 14.04MAC OS 10.13 上都编译成功了,
在使用Ubuntu编译的时候有个坑要注意:

不要把项目克隆到外部硬盘,比如我电脑120G的SSD
还挂了一个1T的机械硬盘,一开始就clone到机械硬盘上了,然后编译
一堆问题,什么ln无法建立链接,chmod命令无效之类的,没把我给毒死,
后面clone到SSD 上一点毛病也没有,全程绿灯!


  • Step 1安装Git与yasm
sudo apt-get install git
sudo apt-get install yasm

  • Step 2:下载,配置SDK与NDK

sdk就不说了,你开发安卓肯定会有的,NDK一般是不默认下载的,
这里也不建议你使用SDK Manager下载的NDK,之前试过有些许问题,
建议去官网下载:https://developer.android.google.cn/ndk/downloads/index.html
NDK的最小版本支持是10e,目前不支持NDK 15!

接着是配置环境变量:

Ubuntu

设置修改下:.bashrc文件,把SDK和NDK配置上:

然后source .bashrc,键入ndk-build -v 看有没有东西输出
验证配置是否生效。

MAC

打开终端,cd到根目录(cd ~),然后新建一个.bash_profile的文件:
进行如下配置

然后输入source .bash_profile,键入ndk-build -v 验证:


  • Step 3:拉取ijkplayer源码
git clone https://github.com/Bilibili/ijkplayer.git ijkplayer-android
cd ijkplayer-android
git checkout -B latest k0.8.4

  • Step 4:初始化android
./init-android.sh

  • Step 5:编译脚本配置

就是自动化编译时的一些配置选项,比如支持什么协议啊,支持什么音视频类型等,
这个配置文件是:config/module.sh,你喜欢可以打开看看这个文件:
比如这里是配置处理什么类型的数据的,enable启用,disable禁用。

另外官方给我们提供了三个模板给我们使用:

module-default.sh:默认,如果你喜欢更多类型可以用这个;
module-lite-hevc.sh:如果您更喜欢较小的二进制大小的编解码器/格式(包括hevc功能)
module-lite.sh:如果您更喜欢较小的二进制大小的编解码器/格式(默认情况下)

反正体积最小,就用module-lite.sh这个就行了,使用也很简单:

rm module.sh
ln -s module-lite.sh module.sh
source module.sh

到此你还可以打开module.sh自行进行修改,比如我只想它支持mp3,
其他格式都不支持,那么可以把不想支持的格式的enable改成disable。


  • Step 6:初始化android支持Https
cd ..
./init-android-openssl.sh

注:如果出现NDK或者SDK找不到,可以执行一下source ~/.bash_profile


  • Step 7:清除一波
cd android/contrib
./compile-openssl.sh clean
./compile-ffmpeg.sh clean

  • Step 8:编译openssl
./compile-openssl.sh all

  • Step 9:编译ffmpeg

这里的话看你需要,如果想编译所有版本的so库,就跟all,如果是特定
CPU架构就跟cpu架构,比如:./compile-ffmpeg.sh armv7a
编译特定需要的肯定是比全部耗时短~

./compile-ffmpeg.sh all

  • Step 10:编译ijkplayer

加all默认编译所有架构的so库,不加默认只编译armv7a架构

./compile-ijk.sh all

编译需要漫长的等待,编译成功后,会在目录下生成一个ijkplayer的工程:

到此,编译一个支持HTTPS的ijkplayer就完成了,接着是怎么用这个东西啦:

再吐槽一句:网上很多教编译的,到此就完了,完全不跟别人说怎么用,
我一开始以为只要把so库放到自己项目的libs下就可以了,结果各种编译
报错,我真服了,大佬们写文章别虎头蛇尾啊!!!

最简单的使用方法,就是把这个项目当成一个library导入到项目中,
就是build.gradle里多一个compile project(':ijkplayer')
然后你就可以用了,记得把你之前写的:

compile 'tv.danmaku.ijk.media:ijkplayer-java:0.8.4'
compile 'tv.danmaku.ijk.media:ijkplayer-armv7a:0.8.4'

这些依赖删掉,不然还是会报不支持HTTPS的!
一般到这里引用到项目里就够了,但是小猪不是个容易满足的人!
所以有了下面的折腾!


3.删减无关东西,生成aar依赖库

觉得又很多无关的东西,说下小猪的期望吧:

  • 1.只是用来播放音乐(exo和example部分可以去掉);
  • 2.只需要armv7a架构的(删除其他架构,并把armv7a的so库放到ijkplayer-java);
  • 3.最后只保留一个ijkplayer-java,导出成ijkplayer.aar文件供自己的项目使用;

接着一步步来把实现小猪的期望吧:


  • Step 1:右键项目 Open Module Settings,点击减号把除了ijkplayer-example
    和ijkplayer-java的依赖都删除:

接着打开ijkplayer-java/src/main/,新建一个libs文件夹,
同时打开ijkplayer-armv7a/main/libs,把里面的armeabi-v7a文件
夹整个拷到ijkplayer-java的libs文件夹下。

然后可以把除了ijkplayer-example和ijkplayer-java的其他都删掉了,
接着修改下ijkplayer-java的build.gradle文件,删掉最后一句,以及
修改下版本信息。

接着编译一波整个工程,运行下,点开simple,随便点首歌看看能否播放,
如果可以正常播放,那么就进入下一步了,导出aar库。


  • Step 2:编译aar库

这个倒是简单,点击右侧gradle,依次打开,右键run就好

执行完毕,会在build/outputs/aar目录下生成aar文件。


  • Step 3:把aar文件添加到项目中

这个也很简单,直接丢到app的libs文件夹下,然后build.gradle
下添加依赖,(笔者直接把ijkplayer-java-release.aar改名成
ijkplayer.aar)

implementation(name: 'ijkplayer', ext: 'aar')

接着,项目里写个简单的播放音乐的代码试试水,按钮点击播放一个音乐:

public class MusicPlayActivity extends AppCompatActivity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_music_play);
        Button btn = findViewById(R.id.button);
        btn.setOnClickListener(v -> {
            IjkMediaPlayer player = new IjkMediaPlayer();
            player.setAudioStreamType(AudioManager.STREAM_MUSIC);
            player.setScreenOnWhilePlaying(true);
            player.setOnPreparedListener(IMediaPlayer::start);
            try {
                player.setDataSource("https:xxxx.mp3");
                player.prepareAsync();
            } catch (IOException e) {
                e.printStackTrace();
            }
        });
    }
}

如果播放正常的话,说明我们的移植非常成功,如果你没有用模块化,
到此就可以结束了,如果你像我一样用了模块化,而且还把音频播放
独立成了一个模块,app -> 音频播放模块 -> ijkplayer.aar
恭喜你,编译直接报错,找不到aar,2333!解决方法的话,你要
接着看下面的啦~


4.模块化,模块使用aar找不到问题解决

需要修改三个build.gradle文件,依次是音频播放模块,app,以及application层级

音频播放模块的build.gradle

app层级的build.gradle:

application层级的build.gradle

接着build一波项目,就可以啦~


小结

耗时几天,总算是编译成功,而且收获颇多了,也懂了了一个道理:
人难免有畏难情绪,对于学习新的东西总会下意识的抗拒,觉得难,
但是大部分时候只是看上去难,当你去学了,并坚持一段时间,你
会发现,其实并没有你想象中那么难~

最后附上缩减后的ijk-player和aar包,有需要的自取:
https://github.com/coder-pig/ijkplayer


©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,835评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,598评论 1 295
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,569评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,159评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,533评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,710评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,923评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,674评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,421评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,622评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,115评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,428评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,114评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,097评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,875评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,753评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,649评论 2 271

推荐阅读更多精彩内容